﻿namespace WPForms.Phone.Model
{
    using System;
    using System.IO;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Markup;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using WPForms.Common.Model;

    /// <summary>
    /// Static helper class, which provides methods to create forminstance from xaml-s.
    /// </summary>
    public static class FormXamlFactory
    {
        /// <summary>
        /// Creates a <see cref="FormInstance"/> from XAML.
        /// </summary>
        /// <param name="xamlStream"><see cref="Stream"/> that contains the XAML declaration of the catalog.</param>
        /// <returns>An instance of <see cref="ModuleCatalog"/> built from the XAML.</returns>
        public static FormInstance CreateFromXaml(Stream xamlStream)
        {
            if (xamlStream == null)
            {
                throw new ArgumentNullException("xamlStream");
            }

            string xaml;
            using (System.IO.StreamReader reader = new System.IO.StreamReader(xamlStream))
            {
                xaml = reader.ReadToEnd();
            }

            var loadedObject = (FormInstance)XamlReader.Load(xaml);
            GenerateKeysForForm(loadedObject);
            return loadedObject;
        }

        /// <summary>
        /// Creates a <see cref="FormInstance"/> from a XAML included as an Application Resource.
        /// </summary>
        /// <param name="builderResourceUri">Relative <see cref="Uri"/> that identifies the XAML included as an Application Resource.</param>
        /// <returns>An instance of <see cref="ModuleCatalog"/> build from the XAML.</returns>
        public static FormInstance CreateFromXaml(Uri builderResourceUri)
        {
            var streamInfo = System.Windows.Application.GetResourceStream(builderResourceUri);

            if ((streamInfo != null) && (streamInfo.Stream != null))
            {
                return CreateFromXaml(streamInfo.Stream);
            }

            return null;
        }

        /// <summary>
        /// Generates the keys for a form.
        /// </summary>
        /// <param name="form">The form.</param>
        private static void GenerateKeysForForm(FormInstance form)
        {
            if (string.IsNullOrEmpty(form.MainSection.Key))
            {
                GenerateKeysForSection(form.MainSection);
            }
        }

        /// <summary>
        /// Generates the keys for the given section.
        /// </summary>
        /// <param name="section">The section.</param>
        /// <param name="current">The current.</param>
        private static void GenerateKeysForSection(FormSection section, string current = null)
        {
            section.Key = current == null ? section.Name : current + "." + section.Name;
            int idx = 0;
            foreach (var child in section.Children)
            {
                if (child is FormSection)
                {
                    GenerateKeysForSection((FormSection)child, section.Key);
                }
                else
                {
                    child.Key = section.Key + "." + child.GetType().Name + idx;
                    idx++;
                }
            }
        }
    }
}
